home *** CD-ROM | disk | FTP | other *** search
- #include "stddefs.h"
- #include "yaklist.h"
-
- //This constructor simply sets the next, previous, and data pointers to NULL
- pyListNode::pyListNode()
- {
- pnNext = pnPrev = NULL;
- pyData = NULL;
- };
-
- //this constructor is a little more interesting, inserting this node
- //between pnNextNode->pnPrev and pnNextNode.
- pyListNode::pyListNode(yakObject * pyThisData, pyListNode * pnNextNode) : //inserts thisData's
- pyData(pyThisData) //node before pnNextNode
- {
- pnNext = pnNextNode;
- pnPrev = pnNextNode->pnPrev;
- pnNextNode->pnPrev = this;
- pnPrev->pnNext = this;
- };
-
- //this destructor JUST deletes the data in pyData. Some have argued that
- //the destructor should also remove the node from the list; I disagree,
- //as I feel that shouldn't be done so automatically.
- pyListNode::~pyListNode(void)
- {
- if (pyData)
- delete pyData;
- };
-
- pyList::pyList()
- {
- nHead.pnNext = nTail.pnNext = &nTail; //nHead and nTail point to each other
- nHead.pnPrev = nTail.pnPrev = &nHead; //so we have meaningful nodes in an
- iNumberInList = 0;
- } //empty list
-
- //this destructor removes each node from the list and then deletes the
- //contents of that node. Note that real objects (not created by pointers)
- //will also be trashed. BE AWARE OF THIS!
- pyList::~pyList()
- {
- while (nHead.pnNext != &nTail)
- removeTail();
- nHead.pnNext = &nTail;
- nTail.pnPrev = &nHead;
- iNumberInList = 0;
- }
-
- //returns the object at the head of the list
- yakObject * pyList::pyHeadData()
- {
- return nHead.pnNext->pyData;
- };
-
- //returns the object at the tail of the list
- yakObject * pyList::pyTailData()
- {
- return nTail.pnPrev->pyData;
- };
-
- //adds a node at the head (beginning) of a list
- void pyList::addHead(yakObject * newData)
- {
- new pyListNode(newData, nHead.pnNext);
- iNumberInList++;
- };
-
- //adds a node at the tail (end) of a list
- void pyList::addTail(yakObject * newData)
- {
- new pyListNode(newData, &nTail);
- iNumberInList++;
- };
-
- //adds a node, using the pyListNode constructor. This is, arguably,
- //a syntactic preference; use would be something like:
- //myPyList.addNode(new pyListNode(new yakObject,
- // new pyListNode(new yakObject,
- // &myPyList.nTail)));
- //making it chainable.
- void pyList::addNode(pyListNode * pnNextNode)
- {
- if(pnNextNode)
- NULL;
- }
-
- //removes and deletes the last item in the list. If the node's bIsTemporary
- //is set to a nonzero value, does not delete the item.
- void pyList::removeTail()
- {
- pyListNode * pnTemp = nTail.pnPrev;
- nTail.pnPrev = pnTemp->pnPrev;
- pnTemp->pnPrev->pnNext = &nTail;
- if (pnTemp->pyData->bIsTemporary && (pnTemp != &nHead))
- delete pnTemp;
- iNumberInList--;
- }
-
- //removes and deletes the first item in the list, similar to removeTail
- void pyList::removeHead()
- {
- pyListNode * pnTemp = nHead.pnNext;
- nHead.pnNext = pnTemp->pnNext;
- pnTemp->pnNext->pnPrev = &nHead;
- if (pnTemp->pyData->bIsTemporary && (pnTemp != &nTail))
- delete pnTemp;
- iNumberInList--;
- }
-
- //returns 1 if nHead.pnNext == &nTail (ie if the object after the head
- //is the tail, the list is empty) otherwise returns 0)
- int pyList::iIsEmpty(void)
- {
- return nHead.pnNext == &nTail;
- };
-
- //constructor for pyListIterator, initializes the list and sets iLooped
- //equal to zero.
- pyListIterator::pyListIterator(pyList & rLFromList)
- {
- initialize(rLFromList);
- iLooped = 0;
- };
-
- //sets the pointers pLMyList and pnThisNode to point to rLFromList
- //and pLMyList->nHead.pnNext.
- void pyListIterator::initialize(pyList & rLFromList)
- {
- pLMyList = &rLFromList;
- pnThisNode = pLMyList->nHead.pnNext;
- };
-
- //increments the listIterator to the next object in the list; if
- //the internal variable iLooped is nonzero and the iterator is
- //at the end of the list, it loops back to the first item.
- yakObject * pyListIterator::operator ++()
- {
- pnThisNode = pnThisNode->pnNext;
- if (iLooped)
- if (!(int)(*this)) setToHead();
- return pnThisNode->pyData;
- };
-
- //decrements the listIterator to the previous item in the list; if the
- //internal variable iLooped is nonzero and the iterator is at the
- //head of the list, it loops back to the last item
- yakObject * pyListIterator::operator --()
- {
- pnThisNode = pnThisNode->pnPrev;
- if (iLooped)
- if (!(char)(*this)) setToTail();
- return pnThisNode->pyData;
- };
-
- //returns the current data at the iterator.
- yakObject * pyListIterator::pyCurrent()
- {
- return pnThisNode->pyData;
- };
-
- //returns 1 if the iterator is valid, 0 if it is at the tail of the list.
- pyListIterator::operator int()
- {
- return (pnThisNode != &(pLMyList->nTail));
- };
-
- //returns 1 if the iterator is valid, 0 if it is at the head of the list.
- pyListIterator::operator char()
- {
- return (pnThisNode != &(pLMyList->nHead));
- };
-
- //sets the iterator to the head (first item) of the list
- void pyListIterator::setToHead()
- {
- pnThisNode = pLMyList->nHead.pnNext;
- };
-
- //sets the iterator the tail (last item) of the list
- void pyListIterator::setToTail()
- {
- pnThisNode = pLMyList->nTail.pnPrev;
- };
-
- //typed iterators (ptListIterator) return a pointer to the correct
- //type of object; ie to get an iterator that returns "int" you would
- //use
- //ptListIterator<int> thisIterator(intList);
-